/**
 * 
 */
package it.unitn.testbed.server.serial;

/**
 * The interface for classes that consume messages received on the serial port.
 * 
 * {@link SerialReceiver} invokes {@link #beginMessage(int, String)} and
 * {@link #endMessage(Object)} once for every message that it receives. In
 * between these invocations, {@link SerialReceiver} invokes for every field of
 * the message {@link #field(Object, String, Object)}.
 * 
 * The user is responsible to allocate state (i.e. {@code context}) that must be
 * returned by {@link #beginMessage(int, String)}. This context is then provided
 * to subsequent calls if the serial receiver sends notifications regarding the
 * same message.
 * 
 * @author Stefan Guna
 * 
 */
public interface MessageConsumer {
	/**
	 * Called whenever a new message has been received.
	 * 
	 * @param moteId
	 *            The ID of the mote sending the message.
	 * @param type
	 *            The type of the message.
	 * @return a context allocated by the user that will be passed back for each
	 *         invokation of {@link #field(Object, String, Object)} and
	 *         {@link #endMessage(Object)} of the same message.
	 */
	public Object beginMessage(int moteId, String type);

	/**
	 * Called to indicate that a message has been completely parsed. No
	 * subsequent calls will be made every again for this context.
	 * 
	 * @param context
	 *            The state returned by {@link #beginMessage(int, String)}.
	 */
	public void endMessage(Object context);

	/**
	 * Called during the parsing of the message to indicate the value of a
	 * field.
	 * 
	 * @param context
	 *            The state returned by {@link #beginMessage(int, String)}.
	 * @param fieldName
	 *            The name of the field.
	 * @param fieldValue
	 *            The field value.
	 */
	public void field(Object context, String fieldName, Object fieldValue);

	/**
	 * Called to describe the type of a message.
	 * 
	 * @param type
	 *            The name of the message.
	 * @param fieldType
	 *            An array denoting the field types.
	 */
	public void newMessageType(String type, FieldType fieldType[]);
}
